package com.wjy.Data_Structure.graph;

import com.wjy.Data_Structure.linearlist.common.LinkedList;
import com.wjy.Data_Structure.linearlist.common.Node;
import com.wjy.Data_Structure.linearlist.listslinkimpl.LinkedListDLNode;

// 双链式存储结构的顶点定义 
public class Vertex {
	private Object info; //顶点信息
	private LinkedList adjacentEdges; //顶点的邻接边表
	private LinkedList reAdjacentEdges; //顶点的逆邻接边表，无向图时为空
	private boolean visited; //访问状态
	private Node vexPosition; //顶点在顶点表中的位置
	private int graphType; //顶点所在图的类型 
	private Object application; //应用。如求短路径时为 Path，求关键路径时为 Vtime 

	/**
	 * 构造方法:在图 G 中引入一个新顶点 
	 * @param g
	 * @param info
	 */
	public Vertex(Graph g, Object info) {
		this.info = info;
		this.adjacentEdges = new LinkedListDLNode();
		this.reAdjacentEdges = new LinkedListDLNode();
		this.visited = false;
		this.graphType = g.getType();
		this.vexPosition = g.insert(this);
		this.application = null;
	}

	/**
	 * 辅助方法:判断顶点所在图的类型
	 * @return
	 */
	private boolean isUnDiGraphNode() {
		return graphType == Graph.UndirectedGraph;
	}

	//获取或设置顶点信
	public Object getInfo() {
		return info;
	}

	public void setInfo(Object info) {
		this.info = info;
	}

	//与顶点的度相关的方法

	/**
	 * 返回点的度
	 * @return
	 */
	public int getDeg() {
		if (isUnDiGraphNode())
			return adjacentEdges.getSize(); //无向图顶点的(出/入)度即为邻接边表的规模
		else
			return getOutDeg() + getInDeg();//有向图顶点的度为出度与入度之和
	}

	/**
	 * 有(无)向图顶点的出度为邻接表规模 
	 * @return
	 */
	public int getOutDeg() {
		return adjacentEdges.getSize();
	}

	public int getInDeg() {
		if (isUnDiGraphNode())
			return adjacentEdges.getSize();//无向图顶点的入度就是它的度 
		else
			return reAdjacentEdges.getSize();//无向图顶点的入度就是它的度 
	}

	//获取与顶点关联的边
	public LinkedList getAdjacentEdges() {
		return adjacentEdges;
	}

	public LinkedList getReAdjacentEdges() {
		if (isUnDiGraphNode())
			return adjacentEdges; //无向图顶点的逆邻接边表就是其邻接边表 
		else
			return reAdjacentEdges;
	}

	/**
	 * 取顶点在所属图顶点集中的位置，即在顶点链接表中的位置。 
	 * @return
	 */
	public Node getVexPosition() {
		return vexPosition;
	}

	//与顶点访问状态相关方法
	public boolean isVisited() {
		return visited;
	}

	public void setToVisited() {
		this.visited = true;
	}

	public void setToUnvisited() {
		this.visited = false;
	}

	//取或设置顶点应用信息
	protected Object getAppObj() {
		return application;
	}

	protected void setAppObj(Object app) {
		this.application = app;
	}

	/**
	 * 重置顶点状态信息 ，包括访问、应用状态。 
	 */
	public void resetStatus() {
		this.visited = false;
		this.application = null;
	}
}
